home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / COMPILER / SATHER / !Sather / Library / Containrs / sa / a_permute < prev    next >
Text File  |  1996-06-01  |  3KB  |  101 lines

  1. ---------------------------> Sather 1.1 source file <--------------------------
  2. -- permute_alg.sa: Permutations of an array
  3. -- Author: Benedict A. Gomes <gomes@tiramisu.ICSI.Berkeley.EDU>
  4. -- Copyright (C) 1995, International Computer Science Institute
  5. -- $Id: a_permute.sa,v 1.4 1996/06/01 21:36:06 gomes Exp $
  6. -- COPYRIGHT NOTICE: This code is provided WITHOUT ANY WARRANTY
  7. -- and is subject to the terms of the SATHER LIBRARY GENERAL PUBLIC
  8. -- LICENSE contained in the file: Sather/Doc/License of the
  9. -- Sather distribution. The license is also available from ICSI,
  10. -- 1947 Center St., Suite 600, Berkeley CA 94704, USA.
  11. -------------------------------------------------------------------
  12.  
  13. class A_PERMUTE{ETP,ATP<$ARR{ETP}} is
  14.    -- Permutation algorithms - a bit bare right now.
  15.    -- Usage:
  16.    --     src: ARRAY{INT} := |1,2,5|;
  17.    --     p: FLIST{INT} := #(|2,1,0|);
  18.    --     dest: ARRAY{INT} := #(3);
  19.    --     i.e. first element of "src" s[0]=1 goes to dest[2]
  20.    --          2nd elt of src (2) goes to dest[1]
  21.    --          3rd elt of src (5) goes to dest[0]
  22.    --     perm_alg: A_PERMUTE{INT,ARRAY{INT}};
  23.    --     perm_alg.permute_into(src,p,dest);
  24.    --     Should permute src into |5,2,1|;
  25.    include COMPARE{ETP};
  26.    
  27.    private is_sorted(a: ATP): BOOL is
  28.       return A_SORT{ETP,ATP}::is_sorted(a);
  29.    end;
  30.    
  31.    -- ------------------- Queries -------------------------
  32.    sorted_is_permutation(p1,p2: ATP): BOOL 
  33.    -- Inputs must be sorted
  34.    -- True if p1 is a permutation of p2. 
  35.    -- Requires self and p2 to both be pre-sorted
  36.       pre is_sorted(p1) and is_sorted(p2)
  37.    is
  38.       sz: INT := p1.size;
  39.       if p2.size /= sz then return false end;
  40.       i: INT := 0; loop until!(i >= sz); 
  41.      if ~elt_eq(p1[i],p2[i]) then return false end;
  42.      i := i + 1;
  43.       end;
  44.       return true;
  45.    end;
  46.  
  47.    -- ------------------- Basic Operations ----------------
  48.    to_reverse(a:ATP) is
  49.       -- Reverse the order of the elements in self. Self may be  void.
  50.       if ~void(a) then
  51.      loop 
  52.         i::=(a.size/2).times!; 
  53.         u::=a.size-i-1; 
  54.         t::=a[i]; a[i]:=a[u]; a[u]:=t;
  55.      end 
  56.       end 
  57.    end;
  58.  
  59.    shuffle(a:ATP) 
  60.       -- Shuffle the elements of self. This is a trivial, obvious
  61.       -- implementation, but not sure if it is sufficient for good randomness
  62.    is
  63.       loop i ::= a.size.times!;
  64.      s ::= RND::int(0,a.size-1);
  65.      t::= a[s]; a[s] := a[i]; a[i] := t;
  66.       end;
  67.    end;
  68.  
  69.    permute_into(src:ATP,new_pos:$ARR{INT},dest:ATP) 
  70.    -- Copy the entries from src into dest using
  71.    -- the permutation array "new_positions" 
  72.    -- src[i] -> dest[new_pos[i]]
  73.    -- Look at new_pos as a mapping from domain indices to range indices
  74.    --     src: ARRAY{INT} := |1,2,5|;
  75.    --     p: FLIST{INT} := #(|2,1,0|);
  76.    --     dest: ARRAY{INT} := #(3);
  77.    --     i.e. first element of "src" s[0]=1 goes to dest[2]
  78.    --          2nd elt of src (2) goes to dest[1]
  79.    --          3rd elt of src (5) goes to dest[0]
  80.    --     permute_into(src,p,dest);  --     Destination= |5,2,1|;
  81.    is
  82.       i ::= 0; sz ::= src.size;
  83.       loop until!(i>=sz);
  84.      new_i: INT := new_pos[i];
  85.      assert(valid_ind(dest,new_i));
  86.      dest[new_i] := src[i];
  87.      i := i +1;
  88.       end;
  89.    end;
  90.       
  91.    private valid_ind(dest: ATP,i: INT): BOOL is
  92.       if i.is_bet(0,dest.size-1) then return true
  93.       else 
  94.      #ERR+"Invalid index:"+i+" for array of size:"+dest.size+"\n";
  95.      return false;
  96.       end;
  97.    end;
  98.    
  99. end;
  100. ------------------------------------------------------------------------------
  101.